import sys
from types import SimpleNamespace

import pygame

from common import (add_score, blue, font_path, get_score, go_next_level, red,
                    set_score, white)

# 设置窗口
screen_width, screen_height = 1300, 800

components = [
    SimpleNamespace(
        image=pygame.image.load("./assets/game_5/1.png"),
        position=(20, 10),
        visible=True,
        label="1",
    ),
    SimpleNamespace(
        image=pygame.image.load("./assets/game_5/2.png"),
        position=(20, 200),
        visible=True,
        label="2",
    ),
    SimpleNamespace(
        image=pygame.image.load("./assets/game_5/3.png"),
        position=(20, 400),
        visible=True,
        label="3",
    ),
    SimpleNamespace(
        image=pygame.image.load("./assets/game_5/4.png"),
        position=(20, 600),
        visible=True,
        label="4",
    ),
]

target_image = pygame.image.load("./assets/game_5/target.png")
font = pygame.font.Font(font_path, 36)
button_text = font.render("开始计时", True, blue)
button_rect = button_text.get_rect(center=(1000, 150))

images = []
for i in range(4):
    images.append(pygame.image.load(f"./assets/game_5/{i}-{i+1}.png"))


def reset():
    global cur_image, cur_image_rect, moving_component, moving_image_rect, running, start_ticks, elapsed_time, cost_time, stage
    cur_image = pygame.image.load("./assets/game_5/0.png")
    cur_image_rect = cur_image.get_rect(topleft=(200, 100), size=(600, 600))

    moving_component = None
    moving_image_rect = None

    running = False
    start_ticks = 0
    elapsed_time = 0
    cost_time = 0
    stage = 0

    for component in components:
        component.visible = True

    set_score(0)


def draw_image(screen):
    # draw target image at (10, 400)
    screen.blit(
        pygame.transform.scale(target_image, (500, 500)),
        (screen_width - 500, screen_height - 500),
    )

    # draw current image
    screen.blit(pygame.transform.scale(cur_image, cur_image_rect.size), cur_image_rect)

    # draw components
    for component in components:
        if component.visible:
            img = pygame.transform.scale(component.image, (200, 200))
            screen.blit(img, component.position)

    # draw moving component
    if moving_component is not None and moving_image_rect is not None:
        screen.blit(
            pygame.transform.scale(moving_component.image, moving_image_rect.size),
            moving_image_rect,
        )


def draw_score(screen):
    global elapsed_time, running, start_ticks, cost_time
    # 显示当前分数
    score_text = font.render(f"当前分数: {get_score()}", True, red)
    score_rect = score_text.get_rect(center=(1000, 50))
    screen.blit(score_text, score_rect)


def draw_timer(screen):
    global elapsed_time, running, start_ticks, cost_time
    # Start game button
    screen.blit(button_text, button_rect)

    # 计时器显示
    if running:
        total_seconds = (pygame.time.get_ticks() - start_ticks + elapsed_time) // 1000
        cost_time = total_seconds
    else:
        total_seconds = elapsed_time // 1000

    minutes = total_seconds // 60
    seconds = total_seconds % 60
    time_string = f"{minutes:02}:{seconds:02}"
    time_text = font.render(time_string, True, red)
    time_rect = time_text.get_rect(center=(1000, 200))
    screen.blit(time_text, time_rect)


reset()


def draw(screen):
    global moving_image_rect, running, start_ticks, elapsed_time, cost_time, moving_component, cur_image, cur_image_rect, stage
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN and running:
            # if the mouse is pressed on a component
            # then drag it
            for component in components:
                if component.visible:
                    if component.image.get_rect(
                        topleft=component.position, size=(200, 200)
                    ).collidepoint(event.pos):
                        moving_component = component
                        moving_component.visible = False
                        moving_image_rect = component.image.get_rect(
                            center=event.pos, size=(200, 200)
                        )
                        break
        elif event.type == pygame.MOUSEBUTTONUP and running:
            # if component is dragged and collade with cur_image_rect, then change the current image
            if moving_component is not None and cur_image_rect.collidepoint(event.pos):
                index = int(moving_component.label) - 1
                if index == stage:
                    cur_image = images[index]
                    stage += 1
                    add_score(10)
                    if stage == 4:
                        elapsed_time = cost_time
                        running = False
                        go_next_level()

                else:
                    moving_component.visible = True
                    add_score(-10)
            elif moving_component is not None:
                # elif reset component to its original position
                moving_component.visible = True
            moving_component = None
            moving_image_rect = None

        elif event.type == pygame.MOUSEMOTION and running:
            if moving_component is not None and moving_image_rect is not None:
                moving_image_rect.center = event.pos

        elif event.type == pygame.MOUSEBUTTONUP and not running:
            if button_rect.collidepoint(event.pos):
                running = True
                start_ticks = pygame.time.get_ticks()

    # 更新屏幕显示
    screen.fill(white)

    draw_score(screen)
    draw_timer(screen)
    draw_image(screen)

    pygame.display.flip()
